﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using QExcel;
using System.Drawing;
using Microsoft.Office.Interop.Excel;

namespace QExcel
{
    public abstract class QSheet
    {
        public Worksheet WorkSeet
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        private List<QItem> items = new List<QItem>();
        public List<QItem> Items
        {
            get
            {
                return items;
            }
            set
            {
                items = value;
            }
        }

        public void OutPut(Worksheet workSheet)
        {
            this.WorkSeet = workSheet;
            this.OutPutItem(workSheet);
        }

        private void OutPutItem(Worksheet workSheet)
        {
            if (!this.exportCustomColumn)
            {
                this.LoadXml();
            }
            foreach (QItem item in this.items)
            {
                if (item is QTable && this.exportCustomColumn)
                {
                    this.BuildRows((QTable)item);
                }

                item.Sheet = this;
                item.Output();
            }
        }

        private bool exportCustomColumn = false;
        /// <summary>
        /// 自否导出自定义列
        /// </summary>
        public bool ExportCustomColumn
        {
            get
            {
                return exportCustomColumn;
            }
            set
            {
                exportCustomColumn = value;
            }
        }

        private string qExportXmlName = "QExport.xml";
        public string QExportXmlName
        {
            get
            {
                return qExportXmlName;
            }
            set
            {
                qExportXmlName = value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public string SheetName
        {
            get;
            set;
        }

        public string SheetText
        {
            get;
            set;
        }

        private Dictionary<string, List<object>> tableDataDic = new Dictionary<string, List<object>>();

        /// <summary>
        /// 设置导出表数据源
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="data"></param>
        public void SetTableData(string tableName, List<object> data)
        {
            if (!this.tableDataDic.ContainsKey(tableName))
            {
                this.tableDataDic.Add(tableName, data);
            }
        }

        /// <summary>
        /// 构建数据
        /// </summary>
        /// <param name="table"></param>
        public void LoadXml()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(AppDomain.CurrentDomain.BaseDirectory + this.qExportXmlName);
            XmlNodeList Rangenodes = doc.SelectNodes(string.Format("Data/{0}//Range", this.SheetName));
            foreach (XmlNode rangeNode in Rangenodes)
            {
                if (rangeNode is XmlElement)
                {
                    XmlElement rangeElement = rangeNode as XmlElement;
                    QRange range = new QRange();
                    range.Content = rangeElement.Attributes["Content"].Value;
                    range.StartRow = Int32.Parse(rangeElement.Attributes["StartRow"].Value);
                    range.StartColumn = Int32.Parse(rangeElement.Attributes["StartColumn"].Value);
                    range.RowCount = Int32.Parse(rangeElement.Attributes["RowCount"].Value);
                    range.ColumnCount = Int32.Parse(rangeElement.Attributes["ColumnCount"].Value);
                    range.Height = Int32.Parse(rangeElement.Attributes["Height"].Value);
                    range.IsBold = Boolean.Parse(rangeElement.Attributes["IsBold"].Value);
                    range.BgColor = ExcelCommon.GetColorFromString(rangeElement.GetAttribute("BgColor"));
                    range.FontColor = ExcelCommon.GetColorFromString(rangeElement.GetAttribute("FontColor"));
                    this.Items.Add(range);
                }
            }
            XmlNodeList nodes = doc.SelectNodes(string.Format("Data/{0}/Table", this.SheetName));
            foreach (XmlNode node in nodes)
            {
                if (node is XmlElement)
                {
                    XmlElement element = node as XmlElement;
                    QTable table = new QTable();
                    try
                    {
                        table.ExportHead = Convert.ToBoolean(element.GetAttribute("ExportHead"));
                    }
                    catch { }
                    table.Name = element.GetAttribute("Name");
                    try
                    {
                        table.StartRow = Int32.Parse(element.Attributes["StartRow"].Value);
                    }
                    catch { };
                    try
                    {
                        table.StartColumn = Int32.Parse(element.Attributes["StartColumn"].Value);
                    }
                    catch { };

                    string fontSize = element.GetAttribute("FontSize");
                    if (!string.IsNullOrEmpty(fontSize))
                    {
                        try
                        {
                            table.FontSize = Int32.Parse(fontSize);
                        }
                        catch { };
                    }

                    string headFontSize = element.GetAttribute("HeadFontSize");
                    if (!string.IsNullOrEmpty(headFontSize))
                    {
                        try
                        {
                            table.HeadFontSize = Int32.Parse(headFontSize);
                        }
                        catch { };
                    }



                    this.BuidChildColumn(table.Columns, element.ChildNodes);
                    //foreach (XmlNode childNode in element.ChildNodes)
                    //{
                    //    if (childNode is XmlElement)
                    //    {
                    //        XmlElement childElement = childNode as XmlElement;
                    //        string widthText = childElement.GetAttribute("Width");
                    //        QColumn column = new QColumn
                    //        {
                    //            Name = childElement.GetAttribute("Name"),
                    //            Text = childElement.GetAttribute("Text"),
                    //            IsCount = string.IsNullOrEmpty(childElement.GetAttribute("IsCount")) ? false : Convert.ToBoolean(childElement.GetAttribute("IsCount")),
                    //            Formula = childElement.GetAttribute("Formula"),
                    //            NumberFormatLocal = childElement.GetAttribute("NumberFormatLocal"),
                    //            BgColor = GetColorFromString(childElement.GetAttribute("BgColor")),
                    //                                        ContentBgColor = GetColorFromString(element.GetAttribute("ContentBgColor"))
                    //        };
                    //        if (!string.IsNullOrEmpty(widthText))
                    //        {
                    //            column.Width = Int32.Parse(widthText);
                    //        }
                    //        table.Columns.AddClumn(column);
                    //        this.BuidChildColumn(column, childElement.ChildNodes);
                    //    }
                    //}
                    BuildRows(table);
                    this.Items.Add(table);
                }
            }

            this.LoadRowStyle();
        }

        /// <summary>
        /// 构建行
        /// </summary>
        /// <param name="table"></param>
        private void BuildRows(QTable table)
        {
            List<object> listData = null;
            if (this.tableDataDic.ContainsKey(table.Name))
            {
                listData = this.tableDataDic[table.Name];
            }
            this.BuildRows(table, listData);
        }

        /// <summary>
        /// 构建行
        /// </summary>
        /// <param name="table"></param>
        protected virtual void BuildRows(QTable table, List<object> objList)
        {
            foreach (object obj in objList)
            {
                QLeafRow leafRow = new QLeafRow { Entity = obj };
                table.Rows.AddRow(leafRow);
            }
        }

        /// <summary>
        /// 构建行(自定义统计行)
        /// </summary>
        /// <param name="table"></param>
        protected virtual void BuildRows(QTable table, List<object> objList, QCountRow countRow)
        {
            int index = 0;
            foreach (object obj in objList)
            {
                QLeafRow leafRow = new QLeafRow { Entity = obj };
                table.Rows.AddRow(leafRow);
                index++;
            }
            countRow.SumCount = index;
            table.Rows.AddRow(countRow);
        }

        /// <summary>
        /// 构建子列
        /// </summary>
        /// <param name="column"></param>
        /// <param name="xmlNodeList"></param>
        private void BuidChildColumn(QColumn column, XmlNodeList xmlNodeList)
        {
            if (xmlNodeList.Count > 0)
            {
                foreach (XmlNode node in xmlNodeList)
                {
                    if (node is XmlElement)
                    {
                        XmlElement element = node as XmlElement;
                        string widthText = element.GetAttribute("Width");
                        string fontSize = element.GetAttribute("FontSize");
                        QColumn childColumn = new QColumn
                        {
                            Name = element.GetAttribute("Name"),
                            Text = element.GetAttribute("Text"),
                            IsCount = string.IsNullOrEmpty(element.GetAttribute("IsCount")) ? false : Convert.ToBoolean(element.GetAttribute("IsCount")),
                            Formula = element.GetAttribute("Formula"),
                            NumberFormatLocal = element.GetAttribute("NumberFormatLocal"),
                            BgColor = ExcelCommon.GetColorFromString(element.GetAttribute("BgColor")),
                            ContentBgColor = ExcelCommon.GetColorFromString(element.GetAttribute("ContentBgColor")),
                        };
                        if (!string.IsNullOrEmpty(widthText))
                        {
                            try
                            {
                                childColumn.Width = Int32.Parse(widthText);
                            }
                            catch { };
                        }

                        if (!string.IsNullOrEmpty(fontSize))
                        {
                            try
                            {
                                childColumn.FontSize = Int32.Parse(fontSize);
                            }
                            catch { };
                        }
                        column.AddColumn(childColumn);
                        this.BuidChildColumn(childColumn, element.ChildNodes);
                    }
                }
            }
        }


        public static Dictionary<string, StyleEntity> RowStyles = new Dictionary<string, StyleEntity>();
        /// <summary>
        /// 加载行样式
        /// </summary>
        private void LoadRowStyle()
        {
            XmlDocument doc = new XmlDocument();
            RowStyles.Clear();
            doc.Load(AppDomain.CurrentDomain.BaseDirectory + this.qExportXmlName);
            XmlNodeList Rangenodes = doc.SelectNodes(string.Format("Data/Style"));
            foreach (XmlNode node in Rangenodes)
            {
                if (node is XmlElement)
                {
                    XmlElement element = node as XmlElement;
                    foreach (XmlNode childNode in element.ChildNodes)
                    {
                        if (childNode is XmlElement)
                        {
                            XmlElement childElement = childNode as XmlElement;

                            StyleEntity styleEntity = new StyleEntity();
                            string colorValue = childElement.GetAttribute("BgColor");
                            if (!string.IsNullOrEmpty(colorValue))
                            {
                                styleEntity.BgColor = ExcelCommon.GetColorFromString(colorValue);
                            }
                            if (!string.IsNullOrEmpty(childElement.GetAttribute("FontColor")))
                            {
                                styleEntity.FontColor = ExcelCommon.GetColorFromString(childElement.GetAttribute("FontColor"));
                            }
                            if (!string.IsNullOrEmpty(childElement.GetAttribute("IsBold")))
                            {
                                try
                                {
                                    styleEntity.IsBold = Boolean.Parse(childElement.GetAttribute("IsBold"));
                                }
                                catch
                                {
                                }
                            }

                            RowStyles.Add(childElement.Name, styleEntity);
                        }
                    }
                }
            }
        }

    }
}
